package main

import (
	"curd-gen/curd"
	"curd-gen/curd/tmpls/api"
	"curd-gen/curd/tmpls/page"
	"curd-gen/curd/tmpls/typed"
	"encoding/json"
	"io/ioutil"
	"os"
	"path"
	"text/template"

	"github.com/urfave/cli/v2"
)

func genCmd() *cli.Command {
	return &cli.Command{
		Name:    "gen",
		Aliases: []string{"g"},
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:  "f",
				Usage: "json defination path",
				Value: "./curd.json",
			},
			&cli.StringFlag{
				Name:  "ftype",
				Usage: "file type, all for default, (api/typed/page)",
				Value: "all",
			},
			&cli.StringFlag{
				Name:  "output",
				Usage: "generated files dir",
				Value: ".",
			},
		},
		Action: func(c *cli.Context) error {
			// read file and parse json
			data, err := ioutil.ReadFile(c.String("f"))
			if err != nil {
				return err
			}

			var curdJson curd.CurdJSON
			if err = json.Unmarshal(data, &curdJson); err != nil {
				return err
			}

			// 分析 curd json
			curdJson = analyzeCurdJson(curdJson)

			// generate files
			ftype := c.String("ftype")
			output := c.String("output")

			if ftype == "all" || ftype == "api" {
				if err = genApiFile(curdJson, output); err != nil {
					return err
				}
			}
			if ftype == "all" || ftype == "typed" {
				if err = genTypedFile(curdJson, output); err != nil {
					return err
				}
			}
			if ftype == "all" || ftype == "page" {
				if err = genPageFile(curdJson, output); err != nil {
					return err
				}
			}

			return nil
		},
	}
}

func analyzeCurdJson(curdJson curd.CurdJSON) curd.CurdJSON {
	// fmt.Printf("curd json: %+v\n", curdJson)

	// TODO nothing todo
	return curdJson
}

// genApiFile 生成 services 下的 api.ts 文件
func genApiFile(curdJson curd.CurdJSON, output string) error {
	filename := "api.ts"
	return genFile(curdJson, api.APITmpl, output, filename)
}

// genTypedFile 生成 services 下的 typings.d.ts 文件
func genTypedFile(curdJson curd.CurdJSON, output string) error {
	filename := "typings.d.ts"
	return genFile(curdJson, typed.TypeDTmpl, output, filename)
}

// genPageFile 生成 page 下的 增删改查页面 文件
func genPageFile(curdJson curd.CurdJSON, output string) error {
	filename := curdJson.Model.Name + "List.tsx"
	err := genFile(curdJson, page.PageListTmpl, output, filename)
	if err != nil {
		return err
	}

	filename = curdJson.Model.Name + "Add.tsx"
	err = genFile(curdJson, page.PageAddTmpl, output, filename)
	if err != nil {
		return err
	}

	filename = curdJson.Model.Name + "Edit.tsx"
	return genFile(curdJson, page.PageEditTmpl, output, filename)
}

func genFile(curdJson curd.CurdJSON, tmpl string, output, filename string) error {
	f, err := os.Create(path.Join(output, filename))
	if err != nil {
		return err
	}
	defer f.Close()

	t := template.New(curdJson.Model.Name)
	t = template.Must(t.Parse(tmpl))
	return t.Execute(f, &curdJson)
}
